<template>
  <div>
    <div style="position: absolute;top:10px;left:40%;z-index: 100">
      <audio id='myAudio' controls>
        <source src="/static/video/music.mp3" type="audio/mp3">
      </audio>
    </div>
    <div id="container"></div>
  </div>
</template>

<script>
import * as THREE from 'three'
import {OrbitControls} from "three/addons/controls/OrbitControls";

let scene;
export default {
  name: "agv-single",
  data() {
    return{
      camera:null,
      cameraCurve:null,
      renderer:null,
      container:null,
      controls:null,
      imageData:[],
      boxMeshs:[],
      boxIndex:0,
      tempData:[],
      myAudio:null,
      analyser:null,
      dataArray:[],
      source:null,
    }
  },
  methods:{
    initScene(){
      scene = new THREE.Scene();
    },
    initCamera(){
      this.camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 10000);
      this.camera.position.set(200,400,200);
    },
    initLight(){
      //添加两个平行光
      const directionalLight1 = new THREE.DirectionalLight(0xffffff, 1.5);
      directionalLight1.position.set(300,300,600)
      scene.add(directionalLight1);
      const directionalLight2 = new THREE.DirectionalLight(0xffffff, 1.5);
      directionalLight2.position.set(600,200,600)
      scene.add(directionalLight2);
    },
    initRound(){
      const AudioContext = window.AudioContext || window.webkitAudioContext;
      let audioCtx = new AudioContext();
      if(!this.source){
        this.source = audioCtx.createMediaElementSource(this.myAudio);//通过audio标签获取播放源
        this.analyser = audioCtx.createAnalyser(); // 创建AnalyserNode 用于分析音频频谱的节点
        this.source.connect(this.analyser);
        this.analyser.connect(audioCtx.destination);
        let bufferLength = this.analyser.frequencyBinCount;
        this.dataArray = new Uint8Array(bufferLength);
      }
    },
    initBox(){
      const img = new Image();
      img.src = '/static/images/img.png';
      img.onload = async () => {
        try {
          const allPixels = await this.getImagePixels(img);
          for (let i = 0; i < allPixels.length; i++) {
            if(i%3 === 0){
              this.tempData.push(JSON.parse(JSON.stringify(allPixels[i])));
            }
          }
          for (let i = 0; i < this.tempData.length; i++) {
            let r = this.tempData[i].r;
            let g = this.tempData[i].g;
            let b = this.tempData[i].b;
            let x = this.tempData[i].x;
            let y = this.tempData[i].y;
            let cubeMaterial = new THREE.MeshPhysicalMaterial({color: 'rgb(' + r + ', ' + g + ', ' + b + ')'});
            let geometry = new THREE.BoxGeometry(1, 1, 1);
            let boxMesh = new THREE.Mesh(geometry, cubeMaterial);
            this.boxMeshs.push(boxMesh)
            this.boxMeshs[i].position.set(x, 1, y);
            scene.add(this.boxMeshs[i]);
          }
        } catch (error) {
          console.error('Error getting image pixels:', error);
        }
      };
    },
    getImagePixels(image) {
      return new Promise((resolve) => {
        const canvas = document.createElement('canvas');
        const ctx = canvas.getContext('2d');
        canvas.width = image.width;
        canvas.height = image.height;
        ctx.drawImage(image, 0, 0);
        const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
        const data = imageData.data;
        const pixels = [];
        for (let i = 0; i < data.length; i += 4) {
            const x = (i / 4) % canvas.width;
            const y = Math.floor((i / 4) / canvas.width);
            const r = data[i];
            const g = data[i + 1];
            const b = data[i + 2];
            const a = data[i + 3];
            pixels.push({x, y, r, g, b, a});
        }
        resolve(pixels); // 返回所有像素的数据数组
      });
    },
    initRenderer(){
      this.renderer = new THREE.WebGLRenderer({ antialias: true });
      this.container = document.getElementById("container")
      this.renderer.setSize(this.container.clientWidth, this.container.clientHeight);
      this.renderer.setClearColor('#AAAAAA', 1.0);
      this.container.appendChild(this.renderer.domElement);
    },
    initControl(){
      this.controls = new OrbitControls(this.camera, this.renderer.domElement);
      this.controls.enableDamping = true;
      this.controls.maxPolarAngle = Math.PI / 2.2;      // // 最大角度
    },
    initAnimate() {
      console.log(scene.children.length)
      requestAnimationFrame(this.initAnimate);
      this.renderer.render(scene, this.camera);
      if(this.analyser){
        this.analyser.getByteFrequencyData(this.dataArray);
        for (let i = 0; i < this.dataArray.length; i++) {
          if(this.boxMeshs[i]){
            this.boxMeshs[i].position.set(this.boxMeshs[i].position.x,this.dataArray[i],this.boxMeshs[i].position.z)
          }if(this.boxMeshs[i*2]){
            this.boxMeshs[i*2].position.set(this.boxMeshs[i*2].position.x,this.dataArray[i],this.boxMeshs[i*2].position.z)
          }if(this.boxMeshs[i*3]){
            this.boxMeshs[i*3].position.set(this.boxMeshs[i*3].position.x,this.dataArray[i],this.boxMeshs[i*3].position.z)
          }
        }
      }
    },
    initPage(){
      this.initScene();
      this.initCamera();
      this.initLight();
      this.initBox();
      this.initRenderer();
      this.initControl();
      this.initAnimate();
    }
  },
  mounted() {
    this.myAudio = document.querySelector('#myAudio');
    this.myAudio.addEventListener('play', () => {
      this.initRound();
    })
    this.initPage()
  }
}
</script>

<style scoped>
#container{
  position: absolute;
  width:100%;
  height:100%;
  overflow: hidden;
}

</style>
